home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / stik_dev / pop / pop.c
Encoding:
C/C++ Source or Header  |  1995-09-16  |  8.5 KB  |  361 lines

  1. /*  pop.c                (c) Steve Adam 1995         steve@netinfo.com.au
  2.  *
  3.  *      A POP3 mail client.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <time.h>
  11.  
  12. #include <tos.h>
  13.  
  14. #include "\include\drivers.h"
  15. #include "\include\transprt.h"
  16.  
  17. #define CON 2
  18.  
  19. /* These definitions are necessary.  transprt.h has external
  20.  * declarations for them.
  21.  */
  22. DRV_LIST *drivers = (DRV_LIST *)NULL;
  23. TPL *tpl = (TPL *)NULL;
  24.  
  25. char *iline;
  26. int16 li = 0;
  27.  
  28. int16 get_tline(int16 cn, int16 ts)
  29. {
  30.     int16 count, c;
  31.     clock_t to = clock() + (clock_t)ts * CLK_TCK;
  32.  
  33.     while (TRUE) {
  34.         count = CNbyte_count(cn);
  35.         if (count < 0)
  36.             return (count);
  37.  
  38.         if (to < clock())
  39.             return (E_USERTIMEOUT);
  40.  
  41.         if (Bconstat(CON)) {
  42.             Bconin(CON);
  43.             return (E_USERTIMEOUT);
  44.         }
  45.  
  46.         else while (count > 0) {
  47.             count -= 1;
  48.             c = CNget_char(cn);
  49.             if (c < E_NODATA)
  50.                 return (c);
  51.             iline[li++] = (char)c;
  52.             if (c == '\n') {
  53.                 iline[li] = '\0';
  54.                 li = 0;
  55.                 return (E_NORMAL);
  56.             }
  57.         }
  58.     }
  59. }
  60.  
  61. int16 pop_mail(int16 cn, FILE *fp)
  62. {
  63.     int16 msgcount, x, tstat;
  64.     char lts[20];
  65.  
  66.     /* Connection is established, so POP it!    */
  67.     /* First count the messages by listing them */
  68.  
  69.     msgcount = 0;
  70.     TCP_send(cn, "LIST\r\n", 6);
  71.     while (TRUE) {
  72.         if ((tstat = get_tline(cn, 120)) < 0) {
  73.             Cconws("get_tline() returns: ");
  74.             Cconws(get_err_text(tstat));
  75.             Cconws("\r\n");
  76.             return (tstat);;
  77.         }
  78.         if (iline[0] == '.' && iline[1] == '\r')
  79.             break;
  80.         else if (isdigit(iline[0]))
  81.             msgcount += 1;
  82.         Cconws(iline);
  83.     }
  84.  
  85.     for (x = 1; x <= msgcount; ++x) {
  86.         strcpy(iline, "RETR ");
  87.         strcat(iline, ltoa((long)x, lts, 10));
  88.         strcat(iline, "\r\n");
  89.         ser_disable();
  90.         fprintf(fp, "From sent@string :%s", iline);
  91.         TCP_send(cn, iline, (int16)strlen(iline));
  92.         ser_enable();
  93.         while (TRUE) {
  94.             if ((tstat = get_tline(cn, 120)) < 0) {
  95.                 Cconws("get_tline() returns: ");
  96.                 Cconws(get_err_text(tstat));
  97.                 Cconws("\r\n");
  98.                 return (tstat);
  99.             }
  100.             if (iline[0] == '.') {
  101.                 if (iline[1] == '\r' && iline[2] == '\n')
  102.                     break;
  103.                 else
  104.                     strcpy(iline, &iline[1]);
  105.             } 
  106.             ser_disable();
  107.             fwrite(iline, 1, strlen(iline), fp);
  108.             ser_enable();
  109.         }
  110.         strcpy(iline, "DELE ");
  111.         strcat(iline, ltoa((long)x, lts, 10));
  112.         strcat(iline, "\r\n");
  113.         TCP_send(cn, iline, (int16)strlen(iline));
  114.         get_tline(cn, 60);
  115.  
  116.         Cconws("Message ");
  117.         Cconws(ltoa((long)x, lts, 10));
  118.         Cconws(" received.\r\n");
  119.     }
  120.  
  121.     TCP_send(cn, "quit\r\n", 6);
  122.     get_tline(cn, 60);
  123.  
  124.     return (E_NORMAL);
  125. }
  126.  
  127. void pop(void)
  128. {
  129.     int16 tstat, cn;
  130.     char username[50], password[50], *ptr;
  131.     FILE *fp = (FILE *)NULL;
  132.     uint32 rhost;
  133.  
  134.     /* Build username and password lines    */
  135.  
  136.     strcpy(username, "USER ");
  137.     ptr = getvstr("POP_USERNAME");
  138.     if (ptr[1] == '\0' && (ptr[0] == '0' || ptr[0] == '1')) {
  139.         Cconws("pop(): POP_USERNAME not set\r\n");
  140.         return ;
  141.     }
  142.     strcat(username, ptr);
  143.     strcat(username, "\r\n");
  144.  
  145.     strcpy(password, "PASS ");
  146.     ptr = getvstr("POP_PASSWORD");
  147.     if (ptr[1] == '\0' && (ptr[0] == '0' || ptr[0] == '1')) {
  148.         Cconws("pop(): POP_PASSWORD not set\r\n");
  149.         return ;
  150.     }
  151.     strcat(password, ptr);
  152.     strcat(password, "\r\n");
  153.  
  154.     iline = KRmalloc((long)1000);   /* That should be enough    */
  155.     if (iline == (char *)NULL) {
  156.         Cconws("Can't allocate line buffer for POP3\r\n");
  157.         return;
  158.     }
  159.  
  160.     ptr = getvstr("POP_MAILBOX");
  161.     if (ptr[1] == '\0' && (ptr[0] == '0' || ptr[0] == '1')) {
  162.         Cconws("pop(): POP_MAILBOX not set\r\n");
  163.         KRfree(iline);
  164.         return;
  165.     }
  166.  
  167.     ser_disable();
  168.     fp = fopen(ptr, "ab");
  169.     ser_enable();
  170.     if (fp == (FILE *)NULL) {
  171.         Cconws("Couldn't open mail file\r\n");
  172.         KRfree(iline);
  173.         return;
  174.     }
  175.  
  176.     ptr = getvstr("POPSERVER");
  177.     if (ptr[1] == '\0' && (ptr[0] == '0' || ptr[0] == '1')) {
  178.         ptr = getvstr("PROVIDER");
  179.         if (ptr[1] == '\0' && (ptr[0] == '0' || ptr[0] == '1')) {
  180.             Cconws("pop(): POPSERVER/PROVIDER not set\r\n");
  181.             KRfree(iline);
  182.             ser_disable();
  183.             fclose(fp);
  184.             ser_enable();
  185.             return ;
  186.         }
  187.     }
  188.  
  189.     tstat = resolve(ptr, (char **)NULL, &rhost, 1);
  190.     if (tstat < 0) {
  191.         Cconws(get_err_text(tstat));
  192.         Cconws("\r\n");
  193.         KRfree(iline);
  194.         ser_disable();
  195.         fclose(fp);
  196.         ser_enable();
  197.         return;
  198.     }
  199.  
  200.     cn = TCP_open(rhost, 110, 0, 1000);
  201.     if (cn < 0) {
  202.         Cconws("TCP_open() returns ");
  203.         Cconws(get_err_text(cn));
  204.         Cconws("\r\n");
  205.         KRfree(iline);
  206.         ser_disable();
  207.         fclose(fp);
  208.         ser_enable();
  209.         return;
  210.     }
  211.  
  212.     tstat = TCP_wait_state(cn, TESTABLISH, 60);
  213.     if (tstat < 0) {
  214.         Cconws("TCP_wait_state() returns: ");
  215.         Cconws(get_err_text(tstat));
  216.         Cconws("\r\n");
  217.     }
  218.  
  219.     if (tstat == 0) {
  220.         Cconws("Connected to POP3 server\r\n");
  221.  
  222.         do {
  223.             if ((tstat = get_tline(cn, 60)) < 0) {
  224.                 Cconws("get_tline() returns: ");
  225.                 Cconws(get_err_text(tstat));
  226.                 Cconws("\r\n");
  227.                 break;
  228.             }
  229.         } while (iline[0] != '+');
  230.     }
  231.  
  232.     if (tstat == 0) {
  233.         Cconws(iline);
  234.  
  235.         TCP_send(cn, username, (int16)strlen(username));
  236.         do {
  237.             if ((tstat = get_tline(cn, 120)) < 0) {
  238.                 Cconws("get_tline() returns: ");
  239.                 Cconws(get_err_text(tstat));
  240.                 Cconws("\r\n");
  241.                 break;
  242.             }
  243.         } while (iline[0] != '+');
  244.     }
  245.  
  246.     if (tstat == 0) {
  247.         Cconws(iline);
  248.  
  249.         TCP_send(cn, password, (int16)strlen(password));
  250.         do {
  251.             if ((tstat = get_tline(cn, 120)) < 0) {
  252.                 Cconws("get_tline() returns: ");
  253.                 Cconws(get_err_text(tstat));
  254.                 Cconws("\r\n");
  255.                 break;
  256.             }
  257.         } while (iline[0] != '+');
  258.     }
  259.  
  260.     if (tstat == 0) {
  261.         Cconws(iline);
  262.  
  263.         tstat = pop_mail(cn, fp);
  264.     }
  265.  
  266.     tstat = (int16)TCP_close(cn, 10);
  267.     Cconws("TCP_close() returns: ");
  268.     Cconws(get_err_text(tstat));
  269.     Cconws("\r\n");
  270.  
  271.     ser_disable();
  272.     fclose(fp);
  273.     ser_enable();
  274.     KRfree (iline);
  275. }
  276.  
  277. /* Function to wait for a keypress    */
  278.  
  279. static void pause(void)
  280. {
  281.     Cconws("Press any key to continue...\r\n"); /* Just like DOS :-)    */
  282.  
  283.     while (Bconstat(CON))
  284.         ;
  285.     Bconin(CON);
  286. }
  287.  
  288. /* Put 'STIK' cookie value into drivers */
  289.  
  290. typedef struct {
  291.     long cktag;
  292.     long ckvalue;
  293. } ck_entry;
  294.  
  295. static long init_drivers(void)
  296. {
  297.     long i = 0;
  298.     ck_entry *jar = *((ck_entry **) 0x5a0);
  299.  
  300.     while (jar[i].cktag) {
  301.         if (!strncmp((char *)&jar[i].cktag, CJTAG, 4)) {
  302.             drivers = (DRV_LIST *)jar[i].ckvalue;
  303.             return (0);
  304.         }
  305.         ++i;
  306.     }
  307.     return (0);    /* Pointless return value...    */
  308. }
  309. static int initialise(void)
  310. {
  311.     static long init_drivers(void);
  312.  
  313.     Supexec(init_drivers);
  314.  
  315.     /* See if we got a value    */
  316.  
  317.     if (drivers == (DRV_LIST *)NULL) {
  318.         Cconws("STiK is not loaded\r\n");
  319.         return (FALSE);
  320.     }
  321.  
  322.     /* Check Magic number    */
  323.  
  324.     if (strcmp(MAGIC, drivers->magic)) {
  325.         Cconws("Magic string doesn't match\r\n");
  326.         return (FALSE);
  327.     }
  328.  
  329.     /* OK, now we can get the address of the "TRANSPORT" layer
  330.      * driver.  If this seems unnecessarily complicated, it's
  331.      * because I tried to create today, what I would like to
  332.      * use later on.  In future, there will be multiple
  333.      * drivers accessible via this method.  With luck, your
  334.      * code will still work with future versions of my software.
  335.      */
  336.  
  337.     tpl = (TPL *)get_dftab(TRANSPORT_DRIVER);
  338.  
  339.     if (tpl == (TPL *)NULL) {
  340.         Cconws("Transport layer *not* loaded\r\n");
  341.         return (FALSE);
  342.     }
  343.     Cconws("Transport layer loaded, Author ");
  344.     Cconws(tpl->author);
  345.     Cconws(", version ");
  346.     Cconws(tpl->version);
  347.     Cconws("\r\n");
  348.  
  349.     return (TRUE);
  350. }
  351.  
  352. void main(void)
  353. {
  354.     Cconws("\033E");
  355.  
  356.     if (initialise())
  357.         pop();
  358.  
  359.     pause();
  360. }
  361.